<?php
/**
 * Description of SimpleLogic
 *
 * @author trunghpb
 */
class SimpleLogic implements infLogic {
    protected $_conn = null;
    protected $logger = null;
    private $table_name = null;
    private $fields = ' * ';


    public function  __construct() {
        $param = _fwiload::loadConfig(_fwia::AppName(), 'db');

        $dbdriver   = $param['dbdriver'];
        $server     = $param['server'];
        $user       = $param['user'];
        $password   = $param['password'];
        $database   = $param['database'];
        $charset    = $param['charset'];
        $debug      = $param['debug'];

        $this->_conn = _fwiDB::createMySQL($dbdriver, $server, $user, $password, $database, $charset, $debug);
    }

    public function insert($aryBean) {
//        $this->logger->begin();
        $intReturn = false;
        if ($this->table_name != null) {
            try {
                $aryBin = array();
                $sql = $this->genSQL($this->table_name, $aryBean, $aryBin, 0);
                if(($this->_conn->Execute($sql, $aryBin)) !== false) {
//                    $this->logger->sql($sql, $this->table_name, $aryBin,FDOC_INSERT);
                    $intReturn =  true;
                }
            } catch (ADODB_Exception $e) {
                throw $e;
            }
        }
//        $this->logger->end();
        return $intReturn;
    }
    /**
     * Edit mot record tuong ung trong table
     *
     * <code>
     * <?php
     * 		public function updateTest(){
     * 			$testdao = new TestDao($this->_objCtrl);
     * 			$bean = array();
     * 			$bean['test_name'] = $this->_objReq->getParam('test_name');
     * 			$bean['test_status'] = 1;
     * 			$condition = array();
     * 			$condition[] = array('','test_id','=',(int)$this->_objReq->getParam('test_id'));
     * 			return $testdao->update($bean,$condition);
     * 		}
     *?>
     *</code>
     *
     * @param array $aryBean
     * @param array $aryCondition
     * @return int $inIsOk;
     */
    public function update($aryBean,$aryCondition) {
//        $this->logger->begin();
        $intReturn = false;
        if ($this->table_name != null) {
            try {
                $data = $this->paserDataForUpdate($aryBean);
                $condition = $this->paserCondition($aryCondition);
                $params = $data['value'];
                if (count($condition['value'])>0)
                    foreach($condition['value'] as $v) {
                        array_push($params,$v);
                    }
                $sql = 'UPDATE  '.$this->table_name.' SET '.$data['field'].$condition['string'];
                if( ($this->_conn->Execute($sql, $params)) !== false) {
//                    $this->logger->sql($sql, $this->table_name, $params,FDOC_UPDATE);
                    $intReturn = true;
                }
            } catch (ADODB_Exception $e) {
                throw $e;
            }
        }
//        $this->logger->end();
        return $intReturn;
    }
    /**
     * doc cac record trong table them cac dieu kien.
     *
     * <code>
     * <?php
     * 		public function selectTest(&$result){
     * 			$testdao = new TestDao($this->_objCtrl);
     * 			$result = array();
     * 			$condition = array();
     * 			$condition[] = array('','test_status','=',1);
     * 			$condition[] = array('ORDER BY','test_id desc');
     * 			return $testdao->select($condition,$result);
     * 		}
     *?>
     *</code>
     *
     * @param array $condition
     * @param array &$result
     * @return int $inIsOk;
     */
    public function select($condition,&$result) {
//        $this->logger->begin();
        $success_flag = true;
        try {
            $condition = $this->paserCondition($condition);
            $sql = 'SELECT SQL_CALC_FOUND_ROWS '.$this->fields.' FROM '.$this->table_name.$condition['string'];
            $result = $this->_conn->GetArray($sql, $condition['value']);
//            $this->logger->sql($sql, $this->table_name, $condition['value'],FDOC_SELECT);

        } catch(ADODB_Exception $e) {
            throw $e;
            $success_flag  = false;
        }
//        $this->logger->end();
        return $success_flag;
    }
    /**
     * doc tat ca cac record trong table
     *
     * <code>
     * <?php
     * 		public function selectAllTest(&$result){
     * 			$testdao = new TestDao($this->_objCtrl);
     * 			$result = array();
     * 			return $testdao->selectAll($result);
     * 		}
     *?>
     *</code>
     *
     * @param array $condition
     * @param array &$result
     * @return int $inIsOk;
     */
    public function selectAll(&$result) {
        if ($this->table_name != null)
            return $this->select(array(),$result);
    }
    /**
     * xoa cac record trong table theo dieu kien
     *
     * <code>
     * <?php
     * 		public function getTest(&$result){
     * 			$testdao = new TestDao($this->_objCtrl);
     * 			$result = array();
     * 			return $testdao->getAll($result);
     * 		}
     *?>
     *</code>
     *
     * @param array $condition
     * @return int $inIsOk;
     */
    public function delete($condition) {
//        $this->logger->begin();
        $intReturn = false;
        if ($this->table_name != null) {
            try {
                $condition = $this->paserCondition($condition);
                $sql = 'DELETE FROM  '.$this->table_name.'  '.$condition['string'];
                if( ($this->_conn->Execute($sql, $condition['value'])) !== false) {
//                    $this->logger->sql($sql, $this->table_name, $aryBin,FDOC_DELETE);
                    $intReturn = true;
                }
            } catch (ADODB_Exception $e) {
                throw $e;
            }
        }
//        $this->logger->end();
        return $intReturn;
    }
    /**
     * tinh tong record duoc tim thay tong mot cau lenh query bat ky
     *
     * @param int &$total
     * @return int $inIsOk;
     */
    public function totalRecord(&$total) {
//        $this->logger->begin();
        $success_flag = true;
        try {
            $sql = 'SELECT FOUND_ROWS() as total_record ';
            $result = $this->_conn->GetArray($sql);
            $total = (count($result)>0)?$result[0]['total_record']:0;
//            $this->logger->sql($sql, $this->table_name,array(),FDOC_SELECT);

        } catch(ADODB_Exception $e) {
            throw $e;
            $success_flag  = false;
        }
//        $this->logger->end();
        return $success_flag;
    }
    /**
     * doc cac record trong database theo tung trang
     *
     * <code>
     * <?php
     * 		public function repeaterTest(&$result){
     * 			$testdao = new TestDao($this->_objCtrl);
     * 			$result = array();
     * 			$condition = array();
     * 			$condition[] = array('','test_status','=',1);
     * 			$condition[] = array('ORDER BY','test_id desc');
     * 			return $testdao->repeater($condition,$result,'page',20);
     * 		}
     *?>
     *</code>
     *
     * @param array $condition
     * @param array $result
     * @param string $pageKey
     * @param int $recordPerPage
     * @return int $inIsOk;
     */
    public function repeater($condition,&$result,$pageKey = "page",$recordPerPage = 30) {
        $tmpResult = array();
        $totalRecord = 0;
        $offset = (((is_numeric($this->_objReq->getParam($pageKey)))?$this->_objReq->getParam($pageKey):1) -1)*$recordPerPage;
        $condition[] = array('LIMIT',"$offset,$recordPerPage");
        $flag = $this->select($condition,&$tmpResult);
        if ($flag == true) {
            $flag =	$this->totalRecord($totalRecord);
            $result['totalPage']  = ceil($totalRecord/$recordPerPage);
            $result['totalRecord'] = $totalRecord;
            $result['recordFirst'] = $offset + 1;
            $result['recordLast'] =  ($offset + $recordPerPage >$totalRecord)?$totalRecord:$offset + $recordPerPage;
            $result['data'] = $tmpResult;
            $result['pageIndex'] =  (is_numeric($this->_objReq->getParam($pageKey)))?$this->_objReq->getParam($pageKey):1;
        }
        return $flag;

    }
    /**
     * tra ve id duoc insert cuoi cung
     *
     * @return int (insertedId)
     */
    public function selectLastInsertedID() {
        return $this->_conn->_insertid();
    }
    public function selectFirst($condition,&$result) {
        $condition[] = array('LIMIT','1');
        $intIsOk = $this->select($condition,$result);
        if (count($result)>0) $result = $result[0];
        return $intIsOk;
    }
    /**
     * ham thuc hien xoa du lieu logic
     *
     * @param string $fieldIdName
     * @param <string,int> $filedIdValue
     * @param string $fieldStatusName
     * @param <string,int> $filedStatusValue
     * @return int $intIsok
     */
    public function deleteLogic($fieldIdName,$filedIdValue,$fieldStatusName,$filedStatusValue=0) {
//        $this->logger->begin();
        $intReturn = false;
        if ($this->table_name != null) {
            try {
                $aryBean = array();
                $aryBean[$fieldIdName] = $filedIdValue;
                $aryCondition = array();
                $aryCondition[] = array('',$fieldStatusName,'=',$filedStatusValue);

                $data = $this->paserDataForUpdate($aryBean);
                $condition = $this->paserCondition($aryCondition);
                $params = $data['value'];
                if (count($condition['value'])>0)
                    foreach($condition['value'] as $v) {
                        array_push($params,$v);
                    }
                $sql = 'UPDATE  '.$this->table_name.' SET '.$data['field'].$condition['string'];
                if( ($this->_conn->Execute($sql, $params)) !== false) {
//                    $this->logger->sql($sql, $this->table_name, $aryBin,FDOC_UPDATE);
                    $intReturn = true;
                }
            } catch (ADODB_Exception $e) {
                throw $e;
            }
        }
//        $this->logger->end();
        return $intReturn;
    }
    /**
     * doc cac record theo field name va value
     *
     * @param string $field_name
     * @param <string,int> $value
     * @return int $intIsOk;
     */
    public function selectByField($field_name,$value) {
//        $this->logger->begin();
        $success_flag = true;
        $condition = array();
        $condition[] = array('',$field_name,'=',$value);
        try {
            $condition = $this->paserCondition($condition);
            $sql = 'SELECT SQL_CALC_FOUND_ROWS '.$this->fields.' FROM '.$this->table_name.$condition['string'];
            $result = $this->_conn->GetArray($sql, $condition['value']);
//            $this->logger->sql($sql, $this->table_name, $condition['value'],FDOC_SELECT);

        } catch(ADODB_Exception $e) {
            throw $e;
            $success_flag  = false;
        }
//        $this->logger->end();
        return $success_flag;
    }
    /**
     * neu $bean dua vao da ton tai trong DB thi tien hanh update, nguoc lai thi insert
     *
     * @param array $bean
     * @return int $intIsOk;
     */
    public function saveData($bean) {
//        $this->logger->begin();
        $intReturn = false;
        if ($this->table_name != null) {
            try {
                $aryBean = $bean;
                $fields = array();
                $op = array();
                $fieldUpdates = array();
                foreach ($bean as $k => $v) {
                    $fields[] = $k;
                    $op[] = '?';
                    $fieldUpdates[] = "$k = ?";
                    array_push($aryBean,$v);
                }
                $sql = "INSERT INTO ".$this->table_name." (".implode(',',$fields).") VALUES (".implode(',',$op).")
		  						ON DUPLICATE KEY UPDATE ".implode(',',$fieldUpdates)."
				";
                if(($this->_conn->Execute($sql, $aryBean)) !== false) {
//                    $this->logger->sql($sql, $this->table_name, $aryBin,FDOC_INSERT);
                    $intReturn =  true;
                }
            } catch (ADODB_Exception $e) {
                throw $e;
            }
        }
//        $this->logger->end();
        return $intReturn;

    }
    /**
     * bat dau mot transaction
     */
    public function startTransaction() {
        $this->_conn->BeginTrans();
    }
    /**
     * commit du lieu cho mot transaction
     */
    public function commitTransaction() {
        $this->_conn->CommitTrans();
    }
    /**
     * rollback lai du lieu cua mot transaction
     */
    public function rollbackTransaction() {
        $this->_conn->RollbackTrans();
    }
    /**
     * doc tat ca cac ten field cua mot table tuong ung
     *
     * @param array $fields
     * @return int $intIsOk
     */
    public function getFields(&$fields) {
//        $this->logger->begin();
        $success_flag = true;
        try {
            $fields = array();
            $sql = "SHOW COLUMNS FROM  ".$this->table_name;
            $result = $this->_conn->GetArray($sql);
//            $this->logger->sql($sql, $this->table_name, null,FDOC_SELECT);
            foreach($result as $v) {
                $fields[] = $v['Field '];
            }
        } catch(ADODB_Exception $e) {
            throw $e;
            $success_flag  = false;
        }
//        $this->logger->end();
        return $success_flag;
    }
    public function setField($fields) {
        $this->fields = ' '.implode(',',$fields).' ';
    }

    public function setTable($table){
        $this->table_name = $table;
    }

    public function genSQL($tableName, $aryDataTable, &$aryDataBinding, $updateFlg, $aryCondition = null,$orderField = null) {

        //String SQL
        $sql = '';
        //check input
        if (!is_array($aryDataTable) || count($aryDataTable) == 0 || strlen(trim($tableName)) == 0) {

            //return string empty
            return $sql;
        }
        //get array keys
        $aryKeys = array_keys($aryDataTable);
        //get array values
        $aryDataBinding  = array_values($aryDataTable);


        if ($updateFlg == 0) {
            //gen sql string for insert
            if (isset($orderField) && strlen(trim($orderField)) > 0 ) {
                //insert with $orderField
                $sql = 'Insert into '.$tableName.'('.join(',', $aryKeys).','.$orderField.')';
                $sql .= ' SELECT '.join(',',array_fill(0, count($aryKeys), '?'));
                $sql .= ',if  (max('.$orderField.') is null, 1, max('.$orderField.') + 1) From '.$tableName;

            } else {
                $sql = 'Insert into '.$tableName.'('.join(',', $aryKeys).')';
                //add values
                $sql .= ' values('.join(',',array_fill(0, count($aryKeys), '?')).')';
            }

        } else {
            //gen sql string for Update
            //get $aryKeyCondition,$aryDataCondition
            if (is_array($aryCondition) && count($aryCondition)  > 0) {
                $aryKeyCondition = array_keys($aryCondition);
                $aryDataCondition  = array_values($aryCondition);
            }

            $sql = 'Update  '.$tableName.' Set  ';
            $sql .= join(' = ? ,', $aryKeys).'=?';

            //add condition Update
            if (isset($aryKeyCondition) && is_array($aryKeyCondition) && count($aryKeyCondition) > 0 ) {
                $sql .=' Where ';
                $sql .= join(" = ? And ", $aryKeyCondition).' = ?';
                $aryDataBinding = array_merge($aryDataBinding,$aryDataCondition);
            }
        }

        //return String SQL
        return $sql;
    }

    protected  function paserCondition($condition) {
        if (count($condition) >0) {
            $flag = false;
            $result = array();
            $result['string'] = '';
            if (is_array($condition))
                foreach ($condition as $v) {
                    switch (count($v)) {
                        case 4:
                            if ($v[3] !== null && $v[3] !== '') {
                                if (stripos(strtolower($v[2]), 'in') !== false) {
                                    $result['string'] .= $v[0].'  '.$v[1].' '.$v[2].' '.$v[3];
                                }else {
                                    $result['string'] .= $v[0].'  '.$v[1].' '.$v[2].' ?  ';
                                    $result['value'][] = $v[3];
                                }
                                $flag = true;
                            }
                            break;
                        case 2:
                            if ($v[1] !== null && $v[1] !== '') {
                                $result['string'] .= ' '.$v[0].' '. $v[1] ;
                            }
                            break;
                    }
                }
            if ($flag) $result['string'] = ' WHERE '.$result['string'];
            return $result;
        }else {
            return array(
                    'string' => '',
                    'value' => array()
            );
        }
    }

    protected function paserDataForUpdate($data) {
        if (count($data) > 0) {
            $result = array();
            foreach($data as $k => $v) {
                $result['field'][] = $k.' = ?';
                $result['vaue'][] = $v;
            }
            return array(
                    'field' =>implode(',',$result['field']),
                    'value' =>$result['vaue']
            );
        }else {
            return array(
                    'field' => '',
                    'value' => array()
            );
        }
    }
}
?>
